package com.fastwire.carriere.rad.controller;

import java.util.ArrayList;
import java.util.List;

import com.fastwire.carriere.common.exception.ResourceException;
import com.fastwire.carriere.dao.DAOException;
import com.fastwire.carriere.dao.DAOFactory;
import com.fastwire.carriere.inventory.vo.ConnectivityVo;
import com.fastwire.carriere.inventory.vo.EndVo;
import com.fastwire.carriere.rad.dao.RadAlarmDao;
import com.fastwire.carriere.rad.dao.RadDao;
import com.fastwire.carriere.rad.dao.RadLogDao;
import com.fastwire.carriere.rad.entity.Rad;
import com.fastwire.carriere.rad.entity.RadAlarm;
import com.fastwire.carriere.rad.entity.RadLog;
import com.fastwire.carriere.rad.entity.RadTermPoint;
import com.fastwire.carriere.rad.entityVo.RadAlarmVo;
import com.fastwire.carriere.rad.entityVo.RadLogVo;
import com.fastwire.carriere.rad.entityVo.RadVo;
import com.fastwire.carriere.rad.snmpadapter.SnmpAdapter;
import com.fastwire.carriere.rad.snmpadapter.SnmpRadConstants;

/**
 * @author Jun Created on 20120501
 */
public class RadProcessControllerImp implements RadProcessController
{
    private final RadDao raddao = DAOFactory.getInstance().getRadDao();
    

    @Override
    public String fullDiscovery(List<String> ipSubnetList) throws DAOException, ResourceException
    {
        RadDiscovery discovery = new RadDiscoveryImp();
        discovery.doConccrentDiscovery(ipSubnetList);

        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.fastwire.carriere.controller.DiscoveryController#fullDiscovery()
     */
    @Override
    public String fullDiscovery() throws DAOException
    {
        // get all the IPs from the current exist
        try
        {
            fullDiscovery(raddao.getAllRadIPs());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public String adhocDiscovery(String ip) throws DAOException
    {
        RadDiscovery discovery = new RadDiscoveryImp();
        return discovery.adhocDiscovery(ip);
    }

    @Override
    public String loopback(String ip, String testType)
    {
        int portType = -1;

        try
        {
            Rad rad = raddao.getRadByIP(ip);
            
            for(RadTermPoint tp : rad.getTermPoints())
            {
                if(SnmpRadConstants.HS_TPTYPE == tp.getType())
                {
                    portType = SnmpRadConstants.HS_TPTYPE;
                    break;
                }
                else if(SnmpRadConstants.E1_TPTYPE == tp.getType())
                {
                    portType = SnmpRadConstants.E1_TPTYPE;
                    break;
                }
            }
        }
        catch (DAOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        if(-1 != portType)
        {
            SnmpAdapter snmpAdp = new SnmpAdapter();
    
            return snmpAdp.loopback(ip, portType, testType);
        }
        
        return "no correct port to do the loopback test.";
    }


    @Override
    public List<RadVo> getRadByNeName(String name) throws DAOException
    {
        List<RadVo> radVoList = new ArrayList<RadVo>();
        
        List<Rad> rads = raddao.getRadByNeName(name);
        for(Rad rad : rads)
        {
            radVoList.add(new RadVo(rad));
        }
        return radVoList;
    }

    @Override
    public RadVo getRadByIP(String ip) throws DAOException
    {
        Rad rad = raddao.getRadByIP(ip);
        
        return new RadVo(rad);
    }

    
    @Override
    public List<RadAlarmVo> getAlarmsByIP(String ip) throws DAOException
    {
        List<RadAlarmVo> alrmsVo = new ArrayList<RadAlarmVo>();

        RadAlarmDao alrmDao = DAOFactory.getInstance().getRadAlarmDao();

        List<RadAlarm> alarms = alrmDao.getAlarmByIP(ip);

        for (RadAlarm alm : alarms)
        {
            alrmsVo.add(new RadAlarmVo(alm));
        }

        return alrmsVo;
    }

    @Override
    public List<RadLogVo> getLogsByIP(String ip) throws DAOException
    {
        discoverLogs(ip);
        
        List<RadLogVo> logsVo = new ArrayList<RadLogVo>();

        RadLogDao logDao = DAOFactory.getInstance().getRadLogDao();

        List<RadLog> logs = logDao.getLogByIP(ip);

        for (RadLog log : logs)
        {
            logsVo.add(new RadLogVo(log));
        }

        return logsVo;
    }

    // get all logs from a RAD
    @Override
    public String discoverLogs(String ip) throws DAOException
    {
        RadLogDao logDao = DAOFactory.getInstance().getRadLogDao();

        SnmpAdapter snmpAdp = new SnmpAdapter();
        List<RadLog> logs = snmpAdp.getRadLogs(ip);

        logDao.saveOrUpdate(logs);

        return null;
    }

    // get all logs from a RAD
    public String discoverAlarms(String ip)
    {
        return null;
    }
    
    // added by Jun on 20120509
    @Override
    public List<ConnectivityVo> stitchRad(List<ConnectivityVo> conList)  throws DAOException
    {
        List<ConnectivityVo> conRad = new ArrayList<ConnectivityVo>();
        
        for(ConnectivityVo con : conList)
        {
            if(con.getaEnd().getAendTp().isEmpty())  // the first link, first node
            {
                List<RadVo> rads = getRadByNeName(con.getAendNE());
                addRad2AEndNE(conRad, rads, con.getaEnd());
            }
           
            if(con.getzEnd().getZendTp().isEmpty()) // the last link, last node
            {
                List<RadVo> rads = getRadByNeName(con.getZendNE());
                addRad2ZEndNE(conRad, rads, con.getzEnd());
            }
        }
        
        conList.addAll(conRad);
        
        return conList;
    }
    
    @Override
    public List<ConnectivityVo> stitchRad2Service(ConnectivityVo con) throws DAOException
    {
        List<ConnectivityVo> conList = new ArrayList<ConnectivityVo>();
        conList.add(con);
        
        List<RadVo> rads = getRadByNeName(con.getAendNE());
        addRad2AEndNE(conList, rads, con.getaEnd());
        
        rads = getRadByNeName(con.getZendNE());
        addRad2ZEndNE(conList, rads, con.getzEnd());
        
        return conList;
    }
    
    // added by Jun on 20120509
    private void addRad2AEndNE(List<ConnectivityVo> conList, List<RadVo> rads, EndVo endVo)
    {
        /*/for test
        RadVo ra = new RadVo();
        ra.setName("Rad123");
        ra.setIpAddr("1.2.3.4");
        ra.setSysName("Rad123");
       
        rads.add(ra);
        // end test
        */
        
        //rads.addAll(getRadsByNE(endVo.getNeVo().getName()));
        
        for(RadVo radVo : rads)
        {
            EndVo radEnd = new EndVo(radVo);
            
            ConnectivityVo conVo = new ConnectivityVo();
            conVo.setName("Rad link");  // ??
            //conVo.setDirectionality("CD_UNI");
            //conVo.setBandwidth("5628");
            
            conVo.setPathType("main");
            
            //conVo.setAendTp(radVo.getName());
            //conVo.setZendTp(endVo.getAendTp());

            conVo.setAendNE(radVo.getSysName());
            conVo.setZendNE(endVo.getNeVo().getNativeEmsName());
            
            conVo.setAendNEType(radVo.getType());  // RAD
            conVo.setZendNEType(endVo.getNeVo().getNeType());
            
            conVo.setaEnd(radEnd);
            conVo.setzEnd(endVo);

            conList.add(conVo);            
        }
    }
    
    // added by Jun on 20120509
    private void addRad2ZEndNE(List<ConnectivityVo> conList, List<RadVo> rads, EndVo endVo)
    {
        /*/ for test
        RadVo ra = new RadVo();
        ra.setName("Rad123");
        ra.setIpAddr("2.1.4.3");
        ra.setSysName("Rad321");
        rads.add(ra);
        //end test        
        */

        for(RadVo radVo : rads)
        {
            EndVo radEnd = new EndVo(radVo);
            
            ConnectivityVo conVo = new ConnectivityVo();
            conVo.setName("Rad link");  // ??
            //conVo.setDirectionality("");
            //conVo.setBandwidth("");
            
            conVo.setPathType("main");
            
            //conVo.setAendTp("");
            //conVo.setZendTp("");

            conVo.setAendNE(endVo.getNeVo().getNativeEmsName());
            conVo.setZendNE(radVo.getSysName());
            
            conVo.setAendNEType(endVo.getNeVo().getNeType());
            conVo.setZendNEType(radVo.getType());
            
            conVo.setaEnd(endVo);
            conVo.setzEnd(radEnd);

            conList.add(conVo);            
        }
    }
    
}
